package com.fingard.dsp.bank.directbank.bocom01;

import java.net.URLEncoder;
import java.util.Date;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextWriter;

public class BOCOM01Base extends DirectBase implements ITcpClient {

	protected static TransIDHelper idHelper = new TransIDHelper(1,9999);

    // 通用参数
    // 交易码
    protected String tr_code = "";
    // 原子交易数缺省填’1’，如果查询多账户信息，请求报文中原子交易数根据账户数来填写。
    protected String atom_tr_count = "1";
    protected String req_no = "";

    protected void writeCommonHeader(XmlTextWriter xmlWriter) throws Exception {
        if (StringHelper.isNullOrEmpty(tr_code)) {
            throw new Exception("未赋值tr_code");
        }

        xmlWriter.writeStartElement("ap");
        xmlWriter.writeStartElement("head");
        xmlWriter.writeElementString("tr_code", tr_code);
        xmlWriter.writeElementString("corp_no", bankFront.org);
        xmlWriter.writeElementString("user_no", bankFront.loginName);
        xmlWriter.writeElementString("req_no", req_no);
        Date tmpDateNow = new Date();
        String queryDate = getBankConfig().getValueAsString("queryDate");
        if(StringHelper.hasAnyChar(queryDate)){
            xmlWriter.writeElementString("tr_acdt", queryDate);
        }else {
            xmlWriter.writeElementString("tr_acdt", Format.Date8Format.format(tmpDateNow));
        }
        xmlWriter.writeElementString("tr_time", Format.Time6Format.format(tmpDateNow));
        xmlWriter.writeElementString("atom_tr_count", atom_tr_count);
        xmlWriter.writeElementString("channel", "0");
        // sign
        // filename
        // ogl_serial_no
        xmlWriter.writeElementClosed("reserved");
        xmlWriter.writeEndElement();
        // <head>
        // <tr_code>210209</tr_code>
        // <corp_no>0000020460</corp_no>
        // <user_no>22222</user_no>
        // <serial_no></serial_no>
        // <req_no>00069676</req_no>
        // <tr_acdt>20100903</tr_acdt>
        // <tr_time>102833</tr_time>
        // <atom_tr_count>1</atom_tr_count>
        // <channel>0</channel>
        // <sign></sign>
        // <filename></filename>
        // <ogl_serial_no></ogl_serial_no>
        // <reserved></reserved>
        // </head>
        // 示例
        // <ap>
        // <head>
        // <tr_code>210201</tr_code>
        // <corp_no>0000002234</corp_no>
        // <user_no>00006</user_no>
        // <req_no>00010239</req_no>
        // <tr_acdt>20061206</tr_acdt>
        // <tr_time>100108</tr_time>
        // <atom_tr_count>1</atom_tr_count>
        // <channel>0</channel>
        // <reserved/>
        // </head>
        //
    }

    /**
     * 汽车金融系统 报文头
     *
     * @param xmlWriter
     * @throws Exception
     */
    protected void writeCommonHeader2(XmlTextWriter xmlWriter) throws Exception {
        if (StringHelper.isNullOrEmpty(tr_code)) {
            throw new Exception("未赋值tr_code");
        }
        String req_userid = getBankConfig().getValueAsString("requserid");
        if (StringHelper.isNullOrEmpty(req_userid)) {
            throw new Exception("Config文件未赋值requserid");
        }

        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        xmlWriter.writeStartElement("mes");
        xmlWriter.writeStartElement("head");
        xmlWriter.writeElementString("REQ_SERVERID", tr_code);
        xmlWriter.writeElementString("REQ_VERSION", "1.00");
        xmlWriter.writeElementString("REQ_USERID", req_userid);
        xmlWriter.writeElementString("REQ_TXSEQ", req_no);
        xmlWriter.writeElementString("REQ_TIME", Format.DateTimeFormat.format(new Date()));
        /*xmlWriter.writeElementString("REQ_NT_SERVER", "");
        xmlWriter.writeElementString("REQ_NT_VERSION", "");
        xmlWriter.writeElementString("REQ_NT_SEQ", "");
        xmlWriter.writeElementString("REQ_NT_RESULT", "");
        xmlWriter.writeElementString("REQ_NT_RETCODE", "");
        xmlWriter.writeElementString("REQ_NT_RETMSG", "");
        xmlWriter.writeElementString("REQ_NT_RESEND", "");*/
        xmlWriter.writeElementClosed("REQ_CHECK");
        xmlWriter.writeEndElement();

    }

    public String[] sendToBank(String p_reqStr, String transType, String commandCode) throws Exception {
        String[] retStr = new String[]{"", ""};
        if (StringHelper.hasAnyChar(transType) && StringHelper.hasAnyChar(commandCode)) {
            this.detailSimulateForBank(bankFront.bankCode, transType, commandCode, p_reqStr, retStr);
            if (retStr[1].length() > 0) {
                return retStr;
            }
        }
        return sendToBank(p_reqStr);
    }

    protected String[] sendToBank(String p_reqStr) throws Exception {
        String[] retStr = new String[]{"", ""};
        if (!bankFront.serverURL.equals("") && bankFront.serverURL != null) {
            WriteBankLogLn("2.提交银行的地址：" + bankFront.serverURL);
            String charsetName = "utf-8";
            //String reqHead = "0" + p_reqStr.getBytes(charsetName).length;
            //reqHead = StringHelper.padRight(reqHead, 7, ' ');
            p_reqStr = "ReqData=" + URLEncoder.encode(p_reqStr, charsetName);//reqHead + p_reqStr;
            WriteBankLogStep2(p_reqStr);
            WebRequest tmpWebRequest = new WebRequest(bankFront.serverURL);
            tmpWebRequest.setConnectTimeout(60000);
            tmpWebRequest.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            tmpWebRequest.setRequestProperty("connection", "Close");
            byte[] tmpToWriteBytes = p_reqStr.getBytes(charsetName);
            retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
            WriteBankLogStep3(retStr[1]);

        } else if (bankFront.serverIP != null && bankFront.serverPort != null) {
            WriteBankLogLn("2.提交银行的地址：" + bankFront.serverIP + ":" + bankFront.serverPort);
            TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);
            String tmpCharset = "GBK";
            byte[] tmpBytesBody = p_reqStr.getBytes(tmpCharset);

            String tmpHead = "0" + tmpBytesBody.length;
            for (int i = tmpHead.length(); i < 7; i++)
                tmpHead += " ";
            // WriteBankLogStep2(tmpHead+p_reqStr);
            byte[] tmpBytesHead = tmpHead.getBytes(tmpCharset);

            byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
            System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
            System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);

            WriteBankLogStep2(tmpHead + p_reqStr);
            TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesSend);
            if (StringHelper.isNullOrEmpty(tmpReceiver.connState)) {
                String tmpBkStr = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
                WriteBankLogStep3(tmpBkStr);
            }
            retStr[0] = tmpReceiver.connState;
            if (tmpReceiver.isCompleted) {
                retStr[1] = new String(tmpReceiver.recBytes, tmpReceiver.contentStartIndex, tmpReceiver.contentLength, tmpCharset);
            } else {
                retStr[1] = tmpReceiver.getConnMsg();
                WriteBankLogLn(retStr[1]);
            }
        }

        return retStr;
    }
    protected String codeToAscii(String p_Code) throws Exception {
        boolean useDspReqSeqID = getBankConfig().getValueAsBool("useDspReqSeqID");
        if (useDspReqSeqID) {
            byte[] Bytes = p_Code.getBytes(getCharset());
            StringBuilder tmpReturnCode = new StringBuilder();

            for (byte b : Bytes) {
                if ((short) b <= 57 && (short) b >= 48) {
                    tmpReturnCode.append(String.valueOf((short) b - 48));
                } else {
                    tmpReturnCode.append("0" + String.valueOf((short) b));
                }
            }
            if (tmpReturnCode.toString().length() > 16) {
                return tmpReturnCode.toString().substring(tmpReturnCode.toString().length() - 16);
            } else {
                return tmpReturnCode.toString();
            }
        } else {
            return p_Code;
        }
    }

    protected static boolean isActiveRetCode(String retCode) {
        if (retCode != null) {
            if (retCode.equals("0000")) {
                return true;
            }
        }
        return false;
    }

    // / <summary>
    // / 处理多域串，开头包含字段名，比如“户名|账号|币种|余额|可用余额|开户日期|账户类型|开户行|错误信息|成功标志|..数据..”
    // / </summary>
    // / <param name="p_MFSText">需解析的多域串值</param>
    // / <param name="p_SplitChar">分隔符，如“|”</param>
    // / <param name="p_FieldNum">字段数</param>
    // / <param name="p_RecordNum">记录行数</param>
    // / <returns>java.util.List<String[]></returns>
    protected java.util.List<String[]> DealMFSText(String p_MFSText, char p_SplitChar, int p_FieldNum, int p_RecordNum) {
        java.util.List<String[]> listStrings = new java.util.ArrayList<String[]>();
        String p_OutMsg = "未知";
        if (p_MFSText == null || p_MFSText.length() == 0) {
            p_OutMsg = "传入多域串值为空";
            return listStrings;// 此时为空
        }
        try {
            int tmpLineCount = 0;// 行数
            int tmpColumnCount = 0;// 字段值计数
            int tmpColumnIndex = 0;// 一个字段值的开始位置

            String[] tmpArrValue = new String[p_FieldNum];// 存每行的值

            for (int i = 0; i < p_MFSText.length(); i++) {
                char tmpEachChar = p_MFSText.charAt(i);// p_MFSText[i];
                if (tmpEachChar == p_SplitChar) {
                    String tmpEachColumnValue = p_MFSText.substring(tmpColumnIndex, i);
                    tmpColumnIndex = i + 1;
                    tmpArrValue[tmpColumnCount] = tmpEachColumnValue;
                    tmpColumnCount++;
                    if (tmpColumnCount >= p_FieldNum) {
                        listStrings.add(tmpArrValue);
                        tmpLineCount++;
                        // 计新的一行
                        tmpColumnCount = 0;
                        tmpArrValue = new String[p_FieldNum];// 存每行的值
                    }

                    if (tmpLineCount - 1 > p_RecordNum && p_MFSText.length() > tmpColumnIndex) {
                        p_OutMsg = "实际内容行数大于预期的行数：" + p_RecordNum;
                        listStrings.clear();
                        return listStrings;
                    }
                }
            }

            if (listStrings.size() - 1 != p_RecordNum) {
                p_OutMsg = "实际内容行数" + (listStrings.size() - 1) + "与预期内容行数" + p_RecordNum + "不相等";
                listStrings.clear();
                return listStrings;
            }
        } catch (Exception ex) {
            p_OutMsg = ex.getMessage();
            WriteBankLogLn("解析银行返回的字符串报错：：" + p_OutMsg);
            return listStrings;
        }
        return listStrings;
    }

    public void getContentLength(TcpReceiver p_receiver) throws Exception {
        // TODO Auto-generated method stub
        if (p_receiver.contentLength == -1) {
            if (p_receiver.readedLength >= 7) {
                // String tmpStrReq = new
                // String(tmpReceiver.reqBytes,tmpReceiver.contentStartIndex,tmpReceiver.contentLength,tmpReceiver.charsetName);
                String tmpHead = new String(p_receiver.recBytes, 1, 6, "GBK");
                WriteBankLogStep3(tmpHead);
                p_receiver.contentLength = Integer.parseInt(tmpHead.trim());
                p_receiver.contentStartIndex = 7;
            }
        }
    }

    protected String getCharset() {
        return getBankConfig().getCharset("UTF-8");
    }

    /**
     * 签收类型
     *
     * @param respType 1-承兑应答 2-收票应答 3-背书转让应答 4-回购式贴现赎回应答 5-质押解除应答 6-提示付款应答 7-保证应答 8-同意清偿应
     * @return 01： 收票签收  02：承兑签收  03：保证签收  04：背书签收  05：提示付款签收  06：清偿签收
     * 07：质押解除签收 08：回购式贴现赎回签收 09：贴现贴入签收 10：转贴现贴入签收 11：质押签收 12：回购式转贴现赎回签
     * 收
     * 收
     * @throws Exception
     */
    protected String recourseCodeChange(int respType) throws Exception {
        String flag = "";
        switch (respType) {
            case 1:
                flag = "02";
                break;//02：承兑签收
            case 2:
                flag = "01";
                break;//01：收票签收
            case 3:
                flag = "04";
                break;//04：背书签收
            case 4:
                flag = "08";
                break;//08：回购式贴现赎回签收
            case 5:
                flag = "07";
                break;//07：质押解除签收
            case 6:
                flag = "05";
                break;//05：提示付款签收
            case 7:
                flag = "03";
                break;//03：保证签收
            case 8:
                flag = "06";
                break;//06：清偿签收
            default:
                flag = "";
                break;
        }
        return flag;
    }

    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return Format.Time12Format.format(tmpDateNow);
    }

    protected String getTrmSeqNum() {
        Date tmpDateNow = new Date();
        return Format.Date6Format.format(tmpDateNow) + idHelper.getNextIDStr();
    }


    /**报文结构风格*/
   	protected void writeCommonHeader_3(XmlTextWriter xmlWriter, BOCOM01Header p_bankHeader) throws Exception{

   		if(StringHelper.isNullOrEmpty(p_bankHeader.tr_code))
   		{
   			throw new Exception("未赋值交易码FTranCode");
   		}
   		if(StringHelper.isNullOrEmpty(p_bankHeader.sign))
   		{
   			throw new Exception("未赋值版本号sign");
   		}
   		String req_userid = getBankConfig().getValueAsString("requserid");
           if (StringHelper.isNullOrEmpty(req_userid)) {
               throw new Exception("Config文件未赋值requserid");
           }
   		xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
           xmlWriter.writeStartElement("mes");
           xmlWriter.writeStartElement("head");
           xmlWriter.writeElementString("REQ_SERVERID", p_bankHeader.tr_code);
           xmlWriter.writeElementString("REQ_VERSION", p_bankHeader.sign);
           xmlWriter.writeElementString("REQ_USERID", req_userid);
           xmlWriter.writeElementString("REQ_TXSEQ", req_no);
           xmlWriter.writeElementString("REQ_TIME", Format.DateTimeFormat.format(new Date()));
           /*xmlWriter.writeElementString("REQ_NT_SERVER", "");
           xmlWriter.writeElementString("REQ_NT_VERSION", "");
           xmlWriter.writeElementString("REQ_NT_SEQ", "");
           xmlWriter.writeElementString("REQ_NT_RESULT", "");
           xmlWriter.writeElementString("REQ_NT_RETCODE", "");
           xmlWriter.writeElementString("REQ_NT_RETMSG", "");
           xmlWriter.writeElementString("REQ_NT_RESEND", "");*/
           xmlWriter.writeElementClosed("REQ_CHECK");
           xmlWriter.writeEndElement();

   	}

   	//上送格式为json格式
     	protected String[] sendToATS(String jsonData) throws Exception {
     		String[] retStr = new String[]{"", ""};
     		WriteBankLogLn("2.提交ATS的地址：" + FGBiz.dspCenter.dspSet.receiptPushServerUrl);

     		//发送银行前置
     		WebRequest tmpRequest = new WebRequest(FGBiz.dspCenter.dspSet.receiptPushServerUrl);
     		tmpRequest.setConnectTimeout(10000);
     		tmpRequest.setRequestProperty("connection", "Close");
     		tmpRequest.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
     		String charsetName = getCharset();
     		StringBuilder data = new StringBuilder();
     		data.append(jsonData);
     		WriteBankLogLn("3.推送给ATS的数据" + data.toString());
     		byte[] tmpWriteBytes = data.toString().getBytes(charsetName);
     		retStr = tmpRequest.upload(tmpWriteBytes, charsetName);
     		WriteBankLogLn("4.返回的数据" + retStr[1]);

     		return retStr;
     	}
}
